﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.AutomaticInterferenceVolumeCreation.CApAIVCSweptVolumesCreator
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.SweptVolume;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands.AutomaticInterferenceVolumeCreation;

internal class CApAIVCSweptVolumesCreator
{
  public const double CLEARANCE = 0.0;
  private CApAIVCSweptVolume m_svCreator;
  private TxSweptVolume_MayProceedCalculation m_mayProceedCallback;
  private CApAIVCLogMessageEventHandler m_logMessage;
  private bool m_shouldStop;
  private Dictionary<ITxRobot, TxObjectList> m_sweptVolumes;

  internal event NextMidLevelStepStartedEventHandler NextMidLevelStep;

  internal event CApSimulationHandler_SimulationInitializedEventHandler SimulationInitialized;

  public TxSweptVolume_MayProceedCalculation Callback
  {
    set => this.m_mayProceedCallback = value;
  }

  public CApAIVCLogMessageEventHandler LogMessage
  {
    set => this.m_logMessage = value;
  }

  public Dictionary<ITxRobot, TxObjectList> SweptVolumes => this.m_sweptVolumes;

  public CApAIVCSweptVolumesCreator()
  {
    this.m_svCreator = (CApAIVCSweptVolume) null;
    // ISSUE: method pointer
    this.m_mayProceedCallback = new TxSweptVolume_MayProceedCalculation((object) this, __methodptr(MayProceed));
    this.m_shouldStop = false;
    this.m_sweptVolumes = new Dictionary<ITxRobot, TxObjectList>();
  }

  public void SweptVolumeCreation(
    TxObjectList sweptVolumeHolders,
    double accuracy,
    bool includeCables)
  {
    int count = ((Collection<ITxObject>) sweptVolumeHolders).Count;
    for (int index = 0; index < count && !this.m_shouldStop; ++index)
    {
      this.FireMidLevelProgress(count);
      ITxSweptVolumeHoldingObject sweptVolumeHolder = ((Collection<ITxObject>) sweptVolumeHolders)[index] as ITxSweptVolumeHoldingObject;
      if (!this.m_shouldStop)
      {
        if (sweptVolumeHolder != null)
        {
          try
          {
            this.FireCreationBeginLogMessage(sweptVolumeHolder);
            this.CreateSingleSweptVolume(sweptVolumeHolder, accuracy, includeCables);
          }
          catch (TxSweptVolumeCalculationFailedException ex)
          {
            this.FireCreationErrorLogMessage(sweptVolumeHolder);
          }
          catch (NullReferenceException ex)
          {
            this.FireCreationErrorLogMessage(sweptVolumeHolder);
          }
          finally
          {
            TxSweptVolume withClearanceType = CApSVSweptVolume.getSVWithClearanceType(sweptVolumeHolder, 0.0);
            if (TxSweptVolume.op_Inequality(withClearanceType, (ITxObject) null))
            {
              this.AddSweptVolume(this.GetSweptVolumeRobot(sweptVolumeHolder), withClearanceType);
              this.FireCreationSuccessLogMessage(sweptVolumeHolder);
            }
          }
        }
      }
    }
  }

  public void AbortCreation()
  {
    this.m_shouldStop = true;
    this.m_svCreator.abort();
    this.m_svCreator = (CApAIVCSweptVolume) null;
  }

  private void CreateSingleSweptVolume(
    ITxSweptVolumeHoldingObject hodlingObject,
    double accuracy,
    bool includeCables)
  {
    this.m_svCreator = new CApAIVCSweptVolume(hodlingObject);
    this.m_svCreator.SimulationInitialized += new CApSimulationHandler_SimulationInitializedEventHandler(this.m_svCreator_SimulationInitialized);
    this.m_svCreator.CallBack = this.m_mayProceedCallback;
    this.m_svCreator.Rewind = true;
    this.m_svCreator.LogMessage = this.m_logMessage;
    this.m_svCreator.createSweptVolume(accuracy, 0.0, includeCables);
  }

  private ITxRobot GetSweptVolumeRobot(ITxSweptVolumeHoldingObject holdingObject)
  {
    ITxRobot sweptVolumeRobot = (ITxRobot) null;
    switch (holdingObject)
    {
      case ITxRoboticOrderedCompoundOperation _:
        sweptVolumeRobot = (holdingObject as ITxRoboticOrderedCompoundOperation).Robot;
        break;
      case ITxRoboticProgram _:
        sweptVolumeRobot = (holdingObject as ITxRoboticProgram).Robot;
        break;
    }
    return sweptVolumeRobot;
  }

  private void AddSweptVolume(ITxRobot robot, TxSweptVolume sweptVolume)
  {
    if (this.m_sweptVolumes.ContainsKey(robot))
    {
      ((Collection<ITxObject>) this.m_sweptVolumes[robot]).Add((ITxObject) sweptVolume);
    }
    else
    {
      TxObjectList txObjectList = new TxObjectList();
      ((Collection<ITxObject>) txObjectList).Add((ITxObject) sweptVolume);
      this.m_sweptVolumes.Add(robot, txObjectList);
    }
  }

  private void FireLogMessage(CApAIVCLogMessage message)
  {
    if (this.m_logMessage == null || message == null)
      return;
    this.m_logMessage((object) this, new CApAIVCLogMessageEventArgs(message));
  }

  private void FireCreationBeginLogMessage(ITxSweptVolumeHoldingObject hodlingObject)
  {
    this.FireLogMessage(new CApAIVCLogMessage(eApAIVCLogCode.SWEPT_VOLUME_CREATION_BEGIN, ((ITxObject) hodlingObject).Name));
  }

  private void FireCreationErrorLogMessage(ITxSweptVolumeHoldingObject holdingObject)
  {
    this.FireLogMessage(new CApAIVCLogMessage(eApAIVCLogCode.SWEPT_VOLUME_CREATION_FAILED, ((ITxObject) holdingObject).Name));
  }

  private void FireCreationSuccessLogMessage(ITxSweptVolumeHoldingObject hodlingObject)
  {
    this.FireLogMessage(new CApAIVCLogMessage(eApAIVCLogCode.SWEPT_VOLUME_CREATION_SUCCEEDED, ((ITxObject) hodlingObject).Name));
  }

  private void FireMidLevelProgress(int nVolumes)
  {
    if (this.NextMidLevelStep == null)
      return;
    this.NextMidLevelStep((object) this, new NextMidLevelStepStartedEventArgs(nVolumes));
  }

  private bool MayProceed(int progress) => true;

  private void m_svCreator_SimulationInitialized(object sender, EventArgs e)
  {
    if (this.SimulationInitialized == null)
      return;
    this.SimulationInitialized(sender, e);
  }
}
